//@author A0096723X
///@class EntriesDisplay
///@Description This class is the helper class of the executor of the BOT program.
///				EntriesDisplay handles the following operations
///				1. Display the vector according to a predefined sorting algorithm and output in the vector<vector<pair, format>>
#ifndef ENTRIESDISPLAy_H
#define ENTRIESDISPLAY_H
#include<string>
#include<vector>
#include<stack>
#include <sstream>
#include <algorithm>

#include <exception>
#include <assert.h>

#include <libqxt-Qt5\include\QxtCore\qxtloggerengine.h>
#include <libqxt-Qt5\include\QxtCore\qxtlogger.h>
#include <libqxt-Qt5\include\QxtCore\QxtLogger>
#include <libqxt-Qt5\include\QxtCore\QxtBasicFileLoggerEngine>
#include <libqxt-Qt5\include\QxtCore\QxtBasicSTDLoggerEngine>

#include "Entry.h"
#include "EntriesSorter.h"
#include "CommonEnum.h"
#include "CommonUtils.h"
#include "FileManager.h"
#include "BotException.h"
using namespace std;
class EntriesDisplay
{
	vector<Entry*> _conflictVector;
	Entry* _newEntry;

	static const int MAX_SIZE = 999;

	static const QString OUTPUT_FORMAT_DATE;
	static const QString OUTPUT_FORMAT_DATE_TO;
	static const QString OUTPUT_FORMAT_TIME_TO;
	static const QString OUTPUT_FORMAT_TIME_BR;
	static const QString OUTPUT_FORMAT_TIME;
	static const QString OUTPUT_FORMAT_TIME_TASK;
	static const QString OUTPUT_FORMAT_DATE_TASK;
	static const string OUTPUT_FORMAT_TODAY_FROM;
	static const string OUTPUT_FORMAT_TODAY_TO;
	static const string OUTPUT_MSG_NO_ENTRIES;
	static const string STRING_EMPTY;

	static const char* OUTPUT_MSG_PAST_ENTRY;
	static const char* OUTPUT_MSG_TODAY_ENTRY;
	static const char* OUTPUT_MSG_BR_IN_DAYS;
	static const char* OUTPUT_MSG_BR_OVER_BY_DAYS;
	static const char* STRING_HEADER_SEARCH;
	static const char* STRING_HEADER_DATE_SEARCH;
	static const char* OUTPUT_MSG_SEARCH_NO_ITEMS;

	//@param Takes in a entry and its corresponding int index.
	//@brief prints out the whole entry to the display format for the different kind of entries, with its index number in front.
	CommonEnum::ReturnString getPastString(Entry* entry, int index);
	CommonEnum::ReturnString getTodayString(Entry* entry, int index);

	//@param Takes in a vector
	//@brief prints out a empty display entry and pushes it into the vector
	void appendEmptyEntry(vector<CommonEnum::ReturnString>& displayVector);

	//@param takes in an Entry* and its corresponding ReturnString
	//@brief compares the entry against the newEntry and conflictVector and assigns the format value to its ReturnString
	void setFormat(Entry* entry, CommonEnum::ReturnString& entryString);

	//@param takes in the vector corresponding to each section for display.
	//@brief Prints out the header display for each section.
	//		 Default display has past, today, tomorrow, future, hence 4 vectors taken in.
	void setDefaultDisplayHeader(vector<CommonEnum::ReturnString>& past,vector<CommonEnum::ReturnString>& today,vector<CommonEnum::ReturnString>& tomorrow, vector<CommonEnum::ReturnString>& future);
	
	//@param takes in vector to add header to, and searchLabel to append to header title
	//@brief creates a new ReturnString and prints the search header title to it, and appends searchLabel, and pushes into displayVector
	void setSearchDisplayHeader(vector<CommonEnum::ReturnString>& displayVector, string searchLabel);
	void setSearchDateHeader(vector<CommonEnum::ReturnString>& displayVector, string searchDateString);	

	//@param takes in an Entry* corresponding to its Entry type.
	//@brief prints out the date or time attributes in a particular format
	//		 different printing formats are used for different entry types, and for different sections
	string printEventDateTime(Entry* entry);
	string printTaskDateTime(Entry* entry);
	string printTodayTaskDateTime(Entry* entry);
	string printTodayEventDateTime(Entry* entry);
	string printTodaySpanningEventDateTime(Entry* entry);

	//@param takes in any Entry*
	//@brief appends to a newline the number of days until the event occurs/has passed
	string getDaysTilString(Entry* entry);

public:
	//@brief initialize a new EntriesDisplay instance
	//The newEntry and conflictVector are used for comparison against when setting the format type
	EntriesDisplay(Entry* newEntry, vector<Entry*> conflictVector);
	~EntriesDisplay(void);

	//@brief takes a vector of entry and prints out in the specified format
	vector<vector<CommonEnum::ReturnString>> getDefaultString(vector<Entry*> entries);
	vector<vector<CommonEnum::ReturnString>> getSearchString(vector<Entry*> entries, string searchLabel);
	vector<vector<CommonEnum::ReturnString>> getSearchDateString(vector<Entry*> entries, string searchDateString);
};

#endif